{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Домашнее задание к лекции «Объекты и классы. Инкапсуляция, наследование и полиморфизм»\n",
    "\n",
    "## Задание № 3. Полиморфизм и магические методы\n",
    "### 1. Перегрузите магический метод __str__ у всех классов.\n",
    "### У проверяющих он должен выводить информацию в следующем виде:\n",
    "\n",
    "- print(some_reviewer)\n",
    "- Имя: Some\n",
    "- Фамилия: Buddy\n",
    "### У лекторов:\n",
    "\n",
    "print(some_lecturer)\n",
    "- Имя: Some\n",
    "- Фамилия: Buddy\n",
    "- Средняя оценка за лекции: 9.9\n",
    "### А у студентов так:\n",
    "\n",
    "- print(some_student)\n",
    "- Имя: Ruoy\n",
    "- Фамилия: Eman\n",
    "- Средняя оценка за домашние задания: 9.9\n",
    "- Курсы в процессе изучения: Python, Git\n",
    "- Завершенные курсы: Введение в программирование\n",
    "\n",
    "### 2. Реализуйте возможность сравнивать (через операторы сравнения) между собой лекторов по средней оценке за лекции и студентов по средней оценке за домашние задания."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Задание № 4. Полевые испытания\n",
    "### Создайте по 2 экземпляра каждого класса, вызовите все созданные методы, а также реализуйте две функции:\n",
    "\n",
    "- для подсчета средней оценки за домашние задания по всем студентам в рамках конкретного курса (в качестве аргументов принимаем список студентов и название курса);\n",
    "- для подсчета средней оценки за лекции всех лекторов в рамках курса (в качестве аргумента принимаем список лекторов и название курса)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 414,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Student:\n",
    "    def __init__(self, name, surname, gender='man'):\n",
    "        self.name = name\n",
    "        self.surname = surname\n",
    "        self.gender = gender\n",
    "        self.finished_courses = []\n",
    "        self.courses_in_progress = []\n",
    "        self.grades = {}\n",
    "    # Реализуем метод выставления оценок лекторам\n",
    "    def rate_lecturer(self, lecturer, course, grade):\n",
    "        if isinstance(lecturer, Lecturer) and course in lecturer.courses_attached and course in self.courses_in_progress:\n",
    "            if course in lecturer.grades_lectors:\n",
    "                lecturer.grades_lectors[course] += [grade]\n",
    "            else:\n",
    "                lecturer.grades_lectors[course] = [grade]\n",
    "        else:\n",
    "            return 'Ошибка'\n",
    "    # Средняя оценка студентов\n",
    "    def midle_s(self):\n",
    "        sum = 0\n",
    "        count = 0\n",
    "        for i in self.grades.values():\n",
    "            for j in i:\n",
    "                sum += j\n",
    "                count += 1\n",
    "        return sum/count\n",
    "\n",
    "    def __str__(self):\n",
    "        r = f'Имя студента: {self.name}\\nФамилия студента: {self.surname}\\nСредняя оценка за домашние задания: {round(self.midle_s(), 1)}\\nКурсы в процессе изучения: {\", \".join(self.courses_in_progress)}\\nЗавершенные курсы: {\", \".join(self.finished_courses)}'\n",
    "        return r\n",
    "    \n",
    "    # Выбор лучшего студента магическим методом __lt__\n",
    "    def __lt__(self, other):\n",
    "        if not isinstance(other, Student):\n",
    "            print('Ошибка')\n",
    "            return\n",
    "        n = self.midle_s() > other.midle_s()\n",
    "        if n == True:\n",
    "            return f'Средняя оценка за ДЗ выше у: {self.name} {self.surname}'\n",
    "        else:\n",
    "            return f'Средняя оценка за ДЗ выше у: {other.name} {other.surname}'\n",
    "    \n",
    "class Mentor:\n",
    "    def __init__(self, name, surname):\n",
    "        self.name = name\n",
    "        self.surname = surname\n",
    "        self.courses_attached = []\n",
    "\n",
    "class Lecturer(Mentor):\n",
    "    def __init__(self, name, surname):\n",
    "        super().__init__(name, surname)\n",
    "        self.grades_lectors = {}\n",
    "\n",
    "    # Расчитываем среднюю оценку лекторам\n",
    "    def midle(self):\n",
    "        sum = 0\n",
    "        count = 0\n",
    "        for i in self.grades_lectors.values():\n",
    "            for j in i:\n",
    "                sum += j\n",
    "                count += 1\n",
    "        return sum/count\n",
    "\n",
    "    # Выбор лучшего лектора магическим методом __lt__\n",
    "    def __lt__(self, other):\n",
    "        if not isinstance(other, Lecturer):\n",
    "            print('Ошибка')\n",
    "            return\n",
    "        n = self.midle() > other.midle()\n",
    "        if n == True:\n",
    "            return f'Средняя оценка за лекции выше у: {self.name} {self.surname}'\n",
    "        else:\n",
    "            return f'Средняя оценка за лекции выше у: {other.name} {other.surname}'\n",
    "\n",
    "    # Форматируем строку метода\n",
    "    def __str__(self):\n",
    "        f_string = f'Имя лектора: {self.name}\\nФамилия лектора: {self.surname}\\nСредняя оценка лектора: {round(self.midle(), 1)}'\n",
    "        return f_string \n",
    "\n",
    "class Reviewer(Mentor):\n",
    "    def __init__(self, name, surname):\n",
    "        super().__init__(name, surname)\n",
    "\n",
    "    # Реализуем метод выставления оценок студентам    \n",
    "    def rate_hw(self, student, course, grade):\n",
    "        if isinstance(student, Student) and course in self.courses_attached and course in student.courses_in_progress:\n",
    "            if course in student.grades:\n",
    "                student.grades[course] += [grade]\n",
    "            else:\n",
    "                student.grades[course] = [grade]\n",
    "        else:\n",
    "            return 'Ошибка'\n",
    "    \n",
    "    # Форматируем строку метода\n",
    "    def __str__(self):\n",
    "        f_string = f'Имя проверяющего: {self.name}\\nФамилия проверяющего: {self.surname}'\n",
    "        return f_string \n",
    "\n",
    "# Задание № 4. Полевые испытания\n",
    "# Создайте по 2 экземпляра каждого класса, вызовите все созданные методы, а также реализуйте две функции:\n",
    "# - для подсчета средней оценки за домашние задания по всем студентам в рамках конкретного курса (в качестве аргументов принимаем список студентов и название курса);\n",
    "# - для подсчета средней оценки за лекции всех лекторов в рамках курса (в качестве аргумента принимаем список лекторов и название курса).\n",
    "\n",
    "def midle_all_S(list_students, name_cource):\n",
    "    sum = 0\n",
    "    count = 0\n",
    "    for i in list_students:\n",
    "        for j in i.grades[name_cource]:\n",
    "            sum += j\n",
    "            count += 1\n",
    "    return round(sum/count, 2)\n",
    "\n",
    "def midle_all_L(list_lectors, name_cource):\n",
    "    sum = 0\n",
    "    count = 0\n",
    "    for i in list_lectors:\n",
    "        for j in i.grades_lectors[name_cource]:\n",
    "            sum += j\n",
    "            count += 1\n",
    "    return round(sum/count, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 415,
   "metadata": {},
   "outputs": [],
   "source": [
    "# У нас учатся два студента\n",
    "Student_1 = Student('Boris', 'Ivanov', )\n",
    "Student_2 = Student('Julia', 'Petrova', 'woman')\n",
    "# На курсах преподают три преподавателя\n",
    "Mentor_1 = Mentor('Steve', 'Jobs')\n",
    "Mentor_2 = Mentor('Bill', 'Gates')\n",
    "Mentor_3 = Mentor('Gauss', 'Krueger')\n",
    "# Пусть лекторами будут\n",
    "Lecturer_1 = Lecturer('Steve', 'Jobs')\n",
    "Lecturer_2 = Lecturer('Gauss', 'Krueger')\n",
    "# Закрепим за нимb курсы\n",
    "Lecturer_1.courses_attached += (['Git'])\n",
    "Lecturer_1.courses_attached += (['Python'])\n",
    "Lecturer_2.courses_attached += (['Git']) \n",
    "Lecturer_2.courses_attached += (['Python'])\n",
    "# Пусть второй преподаватель будет проверяющим\n",
    "Reviewer_1 = Reviewer('Bill', 'Gates')\n",
    "# Закрепим за ним два курса\n",
    "Reviewer_1.courses_attached += (['Python']) \n",
    "Reviewer_1.courses_attached += (['Git']) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 416,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Завершенные курсы и оценки за них\n",
    "Student_1.finished_courses += ['Введение в программирование']\n",
    "Student_1.grades['Введение в программирование'] = [10, 10, 10, 10, 10]\n",
    "Student_2.finished_courses += ['Введение в программирование']\n",
    "Student_2.grades['Введение в программирование'] = [10, 8, 10, 9, 10]\n",
    "# В прогрессе изучения у студентов следующие курсы\n",
    "Student_1.courses_in_progress += ['Python']\n",
    "Student_1.courses_in_progress += ['Git']\n",
    "Student_2.courses_in_progress += ['Python']\n",
    "Student_2.courses_in_progress += ['Git']\n",
    "# Проверяющий выставляют оценки студенту_1\n",
    "Reviewer_1.rate_hw(Student_1, 'Python', 5)\n",
    "Reviewer_1.rate_hw(Student_1, 'Python', 10)\n",
    "Reviewer_1.rate_hw(Student_1, 'Python', 8)\n",
    "Reviewer_1.rate_hw(Student_1, 'Git', 7)\n",
    "Reviewer_1.rate_hw(Student_1, 'Git', 7)\n",
    "Reviewer_1.rate_hw(Student_1, 'Git', 7)\n",
    "Reviewer_1.rate_hw(Student_1, 'Git', 7)\n",
    "# Проверяющий выставляют оценки студенту_2\n",
    "Reviewer_1.rate_hw(Student_2, 'Python', 10)\n",
    "Reviewer_1.rate_hw(Student_2, 'Python', 10)\n",
    "Reviewer_1.rate_hw(Student_2, 'Python', 8)\n",
    "Reviewer_1.rate_hw(Student_2, 'Git', 10)\n",
    "Reviewer_1.rate_hw(Student_2, 'Git', 10)\n",
    "Reviewer_1.rate_hw(Student_2, 'Git', 8)\n",
    "Reviewer_1.rate_hw(Student_2, 'Git', 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 417,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Python': [8, 8], 'Git': [8, 8]}\n",
      "{'Python': [6, 10], 'Git': [6, 5]}\n"
     ]
    }
   ],
   "source": [
    "# Студент_1 выставляет оценки лекторам\n",
    "Student_1.rate_lecturer(Lecturer_1, 'Python', 8)\n",
    "Student_1.rate_lecturer(Lecturer_2, 'Python', 6)\n",
    "Student_1.rate_lecturer(Lecturer_1, 'Git', 8)\n",
    "Student_1.rate_lecturer(Lecturer_2, 'Git', 6)\n",
    "# Студент_2 выставляет оценки лекторам\n",
    "Student_2.rate_lecturer(Lecturer_1, 'Python', 8)\n",
    "Student_2.rate_lecturer(Lecturer_2, 'Python', 10)\n",
    "Student_2.rate_lecturer(Lecturer_1, 'Git', 8)\n",
    "Student_2.rate_lecturer(Lecturer_2, 'Git', 5)\n",
    "# =============\n",
    "print(Lecturer_1.grades_lectors)\n",
    "print(Lecturer_2.grades_lectors)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 418,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "---Lecturer_1---\n",
      "Имя лектора: Steve\n",
      "Фамилия лектора: Jobs\n",
      "Средняя оценка лектора: 8.0\n",
      "---Lecturer_2---\n",
      "Имя лектора: Gauss\n",
      "Фамилия лектора: Krueger\n",
      "Средняя оценка лектора: 6.8\n",
      "---best Lecturer---\n",
      "Средняя оценка за лекции выше у: Steve Jobs\n",
      "---Student_1---\n",
      "Имя студента: Boris\n",
      "Фамилия студента: Ivanov\n",
      "Средняя оценка за домашние задания: 8.4\n",
      "Курсы в процессе изучения: Python, Git\n",
      "Завершенные курсы: Введение в программирование\n",
      "---Student_2---\n",
      "Имя студента: Julia\n",
      "Фамилия студента: Petrova\n",
      "Средняя оценка за домашние задания: 9.4\n",
      "Курсы в процессе изучения: Python, Git\n",
      "Завершенные курсы: Введение в программирование\n",
      "---best Student---\n",
      "Средняя оценка за ДЗ выше у: Julia Petrova\n",
      "---average rating---\n",
      "8.5\n",
      "6.75\n"
     ]
    }
   ],
   "source": [
    "print('---Lecturer_1---')\n",
    "print(Lecturer_1)\n",
    "print('---Lecturer_2---')\n",
    "print(Lecturer_2)\n",
    "print('---best Lecturer---')\n",
    "print(Lecturer_1.__lt__(Lecturer_2))\n",
    "print('---Student_1---')\n",
    "print(Student_1)\n",
    "print('---Student_2---')\n",
    "print(Student_2)\n",
    "print('---best Student---')\n",
    "print(Student_1.__lt__(Student_2))\n",
    "print('---average rating---')\n",
    "print(midle_all_S([Student_1, Student_2], 'Python'))\n",
    "print(midle_all_L([Lecturer_1, Lecturer_2], 'Git'))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.10.7 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.7"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
